<?php

use falcon5\inc\Application;
use falcon5\inc\Base\Common;
use falcon5\inc\Base\WPOption;
use falcon5\inc\Infrastructure\Services\Falcon5Service;
use Dotenv\Dotenv;
use hollisho\helpers\ArrayHelper;
use lucatume\DI52\ContainerException;
use hollisho\helpers\EnvHelper;
use Monolog\Logger;


if (! function_exists('falcon5_app')) {
    /**
     * @param $make
     * @return object
     * @throws ContainerException
     * @desc Get the available container instance.
     * @phpstan-template T of object
     * @phpstan-param class-string<T> $class_name
     *
     * @phpstan-return T
     */
    function falcon5_app($make = null)
    {
        if (is_null($make)) {
            return Application::container();
        }
        
        return Application::container()->make($make);
    }
}

if (! function_exists('falcon5_env')) {
    /**
     * Gets the value of an environment variable.
     *
     * @param string $key
     * @param mixed $default
     * @return mixed
     * @throws ContainerException
     */
    function falcon5_env(string $key, $default = null)
    {
        /** @var Dotenv $env */
        $env = falcon5_app('env');
        return EnvHelper::get($key, $default);
    }
}


if (! function_exists('falcon5_lang')) {
    /**
     * @param string $name
     * @param array $vars
     * @param string $range
     * @return string
     * @desc
     */
    function falcon5_lang(string $name, array $vars = [], string $range = ''): string
    {
        return $name;
    }
}

if (! function_exists('engine_support_languages')) {
    function engine_support_languages(): array
    {
        $engineSupportLang = [];
        try {
            /** @var Falcon5Service $service */
            $service = falcon5_app(Falcon5Service::class);
            $result = $service->supportLang();
            if (ArrayHelper::getValue($result, 'code') == 1) {
                $engineSupportLang = ArrayHelper::getValue($result, 'data');
            }
        } catch (\Exception $e) {
            falcon5_error_log('Caught exception: ' . $e->getMessage());
        }

        if (empty($engineSupportLang)) {
            return ArrayHelper::map($engineSupportLang, 'code', 'name');
        } {
            return falcon5_support_languages();
        }
    }
}


if (!function_exists('falcon5_support_languages')) {
    function falcon5_support_languages(): array
    {
        return [
            'en' => 'English',
            'ar' => 'Arabic',
            'bg' => 'Bulgarian',
            'zh-cn' => 'Chinese (Simplified)',
            'zh-tw' => 'Chinese (Traditional)',
            'hr' => 'Croatian',
            'cs' => 'Czech',
            'da' => 'Danish',
            'nl' => 'Dutch',
            'fi' => 'Finnish',
            'fr' => 'French',
            'de' => 'German',
            'el' => 'Greek',
            'hi' => 'Hindi',
            'it' => 'Italian',
            'ja' => 'Japanese',
            'ko' => 'Korean',
            'no' => 'Norwegian',
            'pl' => 'Polish',
            'pt' => 'Portuguese',
            'ro' => 'Romanian',
            'ru' => 'Russian',
            'es' => 'Spanish',
            'sv' => 'Swedish',
            'ca' => 'Catalan',
            'tl' => 'Filipino',
            'iw' => 'Hebrew',
            'id' => 'Indonesian',
            'lv' => 'Latvian',
            'lt' => 'Lithuanian',
            'sr' => 'Serbian',
            'sk' => 'Slovak',
            'sl' => 'Slovenian',
            'uk' => 'Ukrainian',
            'vi' => 'Vietnamese',
            'sq' => 'Albanian',
            'et' => 'Estonian',
            'gl' => 'Galician',
            'hu' => 'Hungarian',
            'mt' => 'Maltese',
            'th' => 'Thai',
            'tr' => 'Turkish',
            'fa' => 'Persian',
            'af' => 'Afrikaans',
            'ms' => 'Malay',
            'sw' => 'Swahili',
            'ga' => 'Irish',
            'cy' => 'Welsh',
            'be' => 'Belarusian',
            'is' => 'Icelandic',
            'mk' => 'Macedonian',
            'yi' => 'Yiddish',
            'hy' => 'Armenian',
            'az' => 'Azerbaijani',
            'eu' => 'Basque',
            'ka' => 'Georgian',
            'ht' => 'Haitian Creole',
            'ur' => 'Urdu',
            'bn' => 'Bengali',
            'bs' => 'Bosnian',
            'ceb' => 'Cebuano',
            'eo' => 'Esperanto',
            'gu' => 'Gujarati',
            'ha' => 'Hausa',
            'hmn' => 'Hmong',
            'ig' => 'Igbo',
            'jw' => 'Javanese',
            'kn' => 'Kannada',
            'km' => 'Khmer',
            'lo' => 'Lao',
            'la' => 'Latin',
            'mi' => 'Maori',
            'mr' => 'Marathi',
            'mn' => 'Mongolian',
            'ne' => 'Nepali',
            'pa' => 'Punjabi',
            'so' => 'Somali',
            'ta' => 'Tamil',
            'te' => 'Telugu',
            'yo' => 'Yoruba',
            'zu' => 'Zulu',
            'my' => 'Myanmar (Burmese)',
            'ny' => 'Chichewa',
            'kk' => 'Kazakh',
            'mg' => 'Malagasy',
            'ml' => 'Malayalam',
            'si' => 'Sinhala',
            'st' => 'Sesotho',
            'su' => 'Sudanese',
            'tg' => 'Tajik',
            'uz' => 'Uzbek',
            'am' => 'Amharic',
            'co' => 'Corsican',
            'haw' => 'Hawaiian',
            'ku' => 'Kurdish (Kurmanji)',
            'ky' => 'Kyrgyz',
            'lb' => 'Luxembourgish',
            'ps' => 'Pashto',
            'sm' => 'Samoan',
            'gd' => 'Scottish Gaelic',
            'sn' => 'Shona',
            'sd' => 'Sindhi',
            'fy' => 'Frisian',
            'xh' => 'Xhosa'
        ];
    }
}

if (!function_exists('falcon5_wp_current_languages')) {
    function falcon5_wp_current_languages(): string
    {
        $currentLocale = strtolower(get_locale());
        $supportedLocales = ['zh_cn' => 'zh-cn', 'zh_tw' => 'zh-tw', 'zh_hk' => 'zh-tw'];

        if (array_key_exists($currentLocale, $supportedLocales)) {
            return $supportedLocales[$currentLocale];
        }

        $localeParts = explode('_', $currentLocale);
        return in_array($localeParts[0], falcon5_support_languages()) ? $localeParts[0] : 'en';
    }
}




if (! function_exists('falcon5_cache_dir')) {
    function falcon5_cache_dir(): string
    {
        if (defined('FALCON5_CACHE_DIR')) {
            $fc5_cache_path = constant('FALCON5_CACHE_DIR');
        } else {
            $fc5_cache_path = WP_CONTENT_DIR . "/wp-content/cache/falcon5caches/";
        }

        return $fc5_cache_path;
    }
}


if (! function_exists('falcon5_navigator_language')) {
    /**
     * @return string
     */
    function falcon5_navigator_language(): string
    {
        preg_match('/^([a-z\d\-]+)/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $matches);
        $navigatorLanguage = $matches[1];
        $navigatorLanguage = str_replace('-', '_', $navigatorLanguage);
        return strtolower($navigatorLanguage);
    }
}

if (! function_exists('falcon5_is_wp_admin')) {
    /**
     * @return bool
     */
    function falcon5_is_wp_admin(): bool
    {
        /** @phpstan-ignore-next-line */
        return is_admin() && (! wp_doing_ajax() || (wp_doing_ajax() && isset($_SERVER['HTTP_REFERER'])
            && strpos(esc_url_raw($_SERVER['HTTP_REFERER']), 'wp-admin') !== false));
    }
}

if (! function_exists('falcon5_wp_is_rest')) {
    /**
     * Checks if the current request is a WP REST API request.
     * @return boolean
     */
    function falcon5_wp_is_rest()
    {
        $prefix = rest_get_url_prefix();
        if (
            defined('REST_REQUEST') && REST_REQUEST // (#1)
            || isset($_GET['rest_route']) //phpcs:ignore
            && strpos(trim($_GET['rest_route'], '\\/'), $prefix) === 0
        ) { //phpcs:ignore
            return true;
        }
        // (#3)
        $rest_url    = wp_parse_url(site_url($prefix));
        $current_url = wp_parse_url(add_query_arg(array()));

        if (!isset($current_url['path']) || !isset($rest_url['path'])) {
            return false;
        } else {
            return strpos($current_url['path'], $rest_url['path']) === 0;
        }
    }
}


if (! function_exists('falcon5_check_proxy_useragent')) {
    /**
     * Checks if the current ua is Falcon5 Proxy.
     * @return boolean
     */
    function falcon5_check_proxy_useragent(): bool
    {
        $userAgent = $_SERVER['HTTP_USER_AGENT'] ?? null;
        $checkBotVe = strpos($userAgent, 'Falcon5 Proxy');
        if ($userAgent !== null && $checkBotVe) {
            return true;
        }

        return false;
    }
}


if (! function_exists('falcon5_cache_dir_is_writable')) {
    function falcon5_cache_dir_is_writable(): string
    {
        $falcon5_cache_dir = falcon5_cache_dir();
        //try to create dir
        if (!is_dir($falcon5_cache_dir)) {
            mkdir($falcon5_cache_dir, 0755, true);
        }

        $writable = false;
        if (is_writable($falcon5_cache_dir)) {
            $writable = true;
        }

        return $writable;
    }
}

if (! function_exists('falcon5_is_ajax')) {
    function falcon5_is_ajax(): bool
    {
        return isset($_SERVER['CONTENT_TYPE']) && stripos($_SERVER['CONTENT_TYPE'], 'application/json') !== false;
    }
}

if (! function_exists('falcon5_is_rest')) {
    function falcon5_is_rest(): bool
    {
        return isset($_SERVER['HTTP_X_REQUESTED_BY']) && $_SERVER['HTTP_X_REQUESTED_BY'] == 'falcon5';
    }
}

if (! function_exists('falcon5_is_proxy')) {
    function falcon5_is_proxy(): bool
    {
        return isset($_SERVER['HTTP_X_FORWARDED_BY']) && $_SERVER['HTTP_X_FORWARDED_BY'] == 'falcon5';
    }
}

if (! function_exists('check_domain_availability')) {
    function check_domain_availability($domain): bool
    {
        $records = dns_get_record($domain, DNS_A);
        return !empty($records);
    }
}

if (! function_exists('check_domain_http')) {
    function check_domain_http(string $url, string $authorization = null): array
    {
        $ch = curl_init($url);

        // 设置 CURL 选项
        curl_setopt($ch, CURLOPT_NOBODY, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 3);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HEADER, true);  // 获取响应头

        // 如果有授权信息，添加到请求头
        if ($authorization) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, [
                'Authorization: ' . $authorization
            ]);
        }

        $response = curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        // 解析响应头
        $headers = [];
        if ($response) {
            $header_lines = explode("\n", $response);
            foreach ($header_lines as $line) {
                $parts = explode(':', $line, 2);
                if (count($parts) === 2) {
                    $headers[trim($parts[0])] = trim($parts[1]);
                }
            }
        }

        return [
            'url' => $url,
            'http_code' => $http_code,
            'status' => ($http_code >= 200 && $http_code < 400),
            'headers' => $headers
        ];
    }
}

if (! function_exists('get_protocol_and_domain')) {
    /**
     * 解析 URL 获取协议和域名（不含 www 前缀）
     * 
     * @param string $url 完整的 URL
     * @return array 包含协议和域名的数组
     */
    function get_protocol_and_domain(string $url): array
    {
        // 使用 parse_url() 解析 URL
        $parsed_url = parse_url($url);

        // 提取协议部分
        $protocol = $parsed_url['scheme'] ?? '';

        // 提取域名部分
        $domain = $parsed_url['host'] ?? '';

        // 移除域名中的 www 前缀
        $domain = falcon5_remove_www($domain);

        return [
            'protocol' => $protocol,
            'domain' => $domain
        ];
    }
}

if (! function_exists('falcon5_get_protocol')) {
    /**
     * 智能检测当前请求的协议，考虑反向代理情况
     * 
     * @return string 返回协议名称（'http' 或 'https'），不包含 '://'
     */
    function falcon5_get_protocol(): string
    {
        if (
            (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] === 'on' || $_SERVER['HTTPS'] === 1)) ||
            (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') ||
            (isset($_SERVER['HTTP_CF_VISITOR']) && strpos($_SERVER['HTTP_CF_VISITOR'], 'https') !== false)
        ) {
            return 'https';
        }
        return 'http';
    }
}

if (! function_exists('falcon5_admin_url')) {
    /**
     * 获取管理后台 URL，处理子域名和子目录模式下的跨域问题
     *
     * @param string $path 管理后台路径
     * @return string 完整的管理后台 URL
     * @throws ContainerException
     */
    function falcon5_admin_url(string $path = ''): string
    {
        // 获取当前请求的协议
        $protocol = falcon5_get_protocol();

        // 获取 URL 模式设置
        $url_mode = falcon5_app(WPOption::class)->getUrlMode();
        if (defined("FC5_URL_MODE")) {
            $url_mode = FC5_URL_MODE;
        }
        // 根据 URL 模式决定使用哪个域名
        if ($url_mode === 'sub-domain' || $url_mode === 'SUB_DOMAIN') {
            // 子域名模式使用代理主机
            $current_domain = $_SERVER['HTTP_FC5_PROXY_HOST'] ?? $_SERVER['HTTP_HOST'];
            // 构建正确的 admin URL
            return $protocol . '://' . $current_domain . '/wp-admin/' . ltrim($path, '/');
        } else {
            // 子目录模式使用当前主机
            return admin_url($path, $protocol);
        }
    }
}

if (! function_exists('falcon5_home_url')) {
    /**
     * 获取网站首页 URL，处理子域名和子目录模式
     *
     * @return string 网站首页 URL
     * @throws ContainerException
     */
    function falcon5_home_url(): string
    {
        // 获取 URL 模式设置
        $url_mode = falcon5_app(WPOption::class)->getUrlMode();
        if (defined("FC5_URL_MODE")) {
            $url_mode = FC5_URL_MODE;
        }
        // 获取当前请求的协议
        $protocol = falcon5_get_protocol();

        // 根据 URL 模式决定使用哪个域名
        if ($url_mode === 'sub-domain' || $url_mode === 'SUB_DOMAIN') {
            // 子域名模式使用代理主机或当前主机
            $current_domain = $_SERVER['HTTP_FC5_PROXY_HOST'] ?? $_SERVER['HTTP_HOST'];
            // 构建正确的 home URL
            return $protocol . '://' . $current_domain;
        }

        // 子目录模式使用当前主机
        return home_url('', $protocol);
    }
}


if (! function_exists('get_authorization')) {
    /**
     * 获取授权信息
     * @return mixed|null
     */
    function get_authorization()
    {
        $authorization = null;

        if (!empty($_SERVER['HTTP_AUTHORIZATION'])) {
            // 优先使用 HTTP_AUTHORIZATION
            $authorization = $_SERVER['HTTP_AUTHORIZATION'];
        } elseif (!empty($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
            // 如果 HTTP_AUTHORIZATION 不存在，尝试使用 REDIRECT_HTTP_AUTHORIZATION
            $authorization = $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
        } elseif (!empty(Common::getFc5AuthUsername()) && !empty(Common::getFc5AuthPassword())) {
            $authorization = "Basic " . base64_encode(sprintf("%s:%s", Common::getFc5AuthUsername(), Common::getFc5AuthPassword()));
        }

        return $authorization;
    }
}

if (! function_exists('falcon5_remove_www')) {
    /**
     * 移除域名中的 www 前缀
     * 
     * @param string $domain 原始域名
     * @return string 处理后的域名
     */
    function falcon5_remove_www(string $domain): string
    {
        if (strpos($domain, 'www.') === 0) {
            return substr($domain, 4);
        }

        return $domain;
    }
}

if (! function_exists('falcon5_log')) {
    function falcon5_log(): Logger
    {
        /** @var Logger $logger */
        $logger = falcon5_app('monolog');
        return $logger;
    }
}


if (! function_exists('falcon5_log_dir')) {
    function falcon5_log_dir(): string
    {
        if (defined('FALCON5_LOGS_DIR')) {
            $fc5_logs_path = constant('FALCON5_LOGS_DIR');
        } elseif (defined('UPLOADS')) {
            $fc5_logs_path = ABSPATH . constant('UPLOADS') . "/logs/";
        } else {
            $fc5_logs_path = WP_CONTENT_DIR . "/uploads/logs/";
        }

        return $fc5_logs_path;
    }
}



if (! function_exists('falcon5_log_dir_is_writable')) {
    function falcon5_log_dir_is_writable($auto_create = false): string
    {
        $falcon5_log_dir = falcon5_log_dir();

        if ($auto_create && !file_exists($falcon5_log_dir)) {
            wp_mkdir_p($falcon5_log_dir);
        }

        //try to create dir
        if (!is_dir($falcon5_log_dir)) {
            mkdir($falcon5_log_dir, 0755, true);
        }

        $writable = false;
        if (is_writable($falcon5_log_dir)) {
            $writable = true;
        }

        return $writable;
    }
}


if (! function_exists('falcon5_error_log')) {
    function falcon5_error_log($message)
    {
        /** @var Logger $logger */
        $logger = falcon5_app('monolog');
        $logger->error($message);
    }
}
if (! function_exists('fc5_home_lang_url')) {
    //init home_url
    function fc5_home_lang_url()
    {
        $toHost = $_SERVER["HTTP_FC5_PROXY_HOST"]??"";
        if (!$toHost) {
            $requestUrl = home_url() . $_SERVER["REQUEST_URI"];
            $urlInfo = parse_url($requestUrl);
            $host = $urlInfo['host'];
            $path = trim($urlInfo['path'], '/');
            $targetLnag = "";
            if (stripos($path, '/')) {
                $targetLnag = explode('/', $path)[0];
            } else {
                $targetLnag = $path;
            }
            if ($path) {
                $falcon5Option = falcon5_app(WPOption::class);
                if (in_array($targetLnag, $falcon5Option->getAllowedLanguages())) {
                    $toHost = $host . '/' . $targetLnag;
                }
            }
        }
        //$lang= fc5_addLanguageToUrl("https://wp1.52bugu.com", $toHost);
        
        add_filter('home_url', function ($url, $path, $scheme) use($toHost){
            global $wp;
            if ($toHost) {
                return fc5_addLanguageToUrl($url, $toHost);
            } else {
                return $url;
            }
        }, 100, 4);
    }
}

if (! function_exists('fc5_extractLanguageFromUrl')) {

    function fc5_extractLanguageFromUrl($targetUrl)
    {
        $pattern = '#^([^/]+)/(?!/)([^/]+)$#';
        if (preg_match($pattern, $targetUrl, $matches)) {
            return $matches[2];
        }
        $pattern = '#https?://([^/]+)/([^/]+)#';
        if (preg_match($pattern, $targetUrl, $matches)) {
            return $matches[2];
        }

        return null;
    }
}
if (! function_exists('fc5_addLanguageToUrl')) {
    function fc5_addLanguageToUrl($url, $targetUrl)
    {
        $languageCode = fc5_extractLanguageFromUrl($targetUrl);

        if ($languageCode) {
            return preg_replace(
                '#(https?://[^/]+)(/.*)?$#',
                '$1/' . $languageCode . '$2',
                $url
            );
        }

        return $url;
    }
}
